home *** CD-ROM | disk | FTP | other *** search
- /* Horizon and window/screen clearing */
- /* Written by Dave STampe, December 1993 */
- /* All algortims and code in this module by Dave Stampe */
-
- /*
- This code is part of the REND386 project, created by Dave Stampe and
- Bernie Roehl.
-
- Copyright 1992, 1993, 1994 by Dave Stampe and Bernie Roehl.
-
- May be freely used to write software for release into the public domain;
- all commercial endeavours MUST contact BOTH Bernie Roehl and Dave Stampe
- for permission to incorporate any part of this software into their
- products! Usually there is no charge for under 50-100 items for
- low-cost or shareware, and terms are reasonable. Any royalties are used
- for development, so equipment is often acceptable payment.
-
- ATTRIBUTION: If you use any part of this source code or the libraries
- in your projects, you must give attribution to REND386, Dave Stampe,
- and Bernie Roehl in your documentation, source code, and at startup
- of your program. Let's keep the freeware ball rolling! No more
- code ripoffs please.
-
- CONTACTS: dstampe@psych.toronto.edu, broehl@sunee.uwaterloo.ca
- See the COPYRITE.H file for more information.
- */
-
- /* Contact: dstampe@sunee.waterloo.edu */
-
- #include <stdio.h>
- #include <dos.h>
- #include <stdlib.h> /* labs */
-
- #include "3dstruct.h"
- #include "rendpriv.h"
- #include "renderer.h"
- #include "intmath.h"
-
- #include "f3dkitd.h" // for block clears
-
- static void band_horizon(VIEW *v, int page, long step, int nstep, int *colorlist)
- {
- int l = v->left;
- int r = v->right;
- int t = v->top;
- int b = v->bottom;
- int i, j, k;
- int vert = 0;
- int mfup, mfdn;
- int upright;
- int cd = 1; /* step direction in thru color list */
-
- int vx[10],vy[10];
-
- long offset;
-
- int olx, orx, oly, ory;
- int nlx, nrx, nly, nry;
-
- if(nstep==0) /* just clear screen totally */
- {
- clr_block(l, t, r, b-1, page, colorlist[0]);
- return;
- }
-
- if(nstep>20) nstep = 20;
- offset = -(step * nstep)/2; /* uppermost position */
-
- mfup = (above_horizon(l,t,v,offset) ) + /* corners with top of horizon */
- (above_horizon(r,t,v,offset)<<1) +
- (above_horizon(l,b,v,offset)<<2) +
- (above_horizon(r,b,v,offset)<<3) ;
-
- mfdn = (above_horizon(l,t,v,-offset) ) + /* corners with bot of horizon */
- (above_horizon(r,t,v,-offset)<<1) +
- (above_horizon(l,b,v,-offset)<<2) +
- (above_horizon(r,b,v,-offset)<<3) ;
-
- if(mfup==15) /* sky only case */
- {
- clr_block(l, t, r, b-1, page, colorlist[0]);
- return;
- }
- if(mfdn==0) /* ground only case */
- {
- clr_block(l, t, r, b-1, page, colorlist[nstep]);
- return;
- }
-
- if(labs(v->eye_xform[0][1]) > labs(v->eye_xform[1][1]) ) /* check slope */
- {
- vert++; /* horizon is more vertical than horizontal */
- upright = (v->eye_xform[0][1]>=0); /* sky on left */
- }
- else upright = (v->eye_xform[1][1]>=0); /* sky on top */
-
- if(!upright) /* will work backwards through colors */
- { /* and through horizon offsets */
- cd = -1;
- colorlist += nstep;
- step = -step;
- offset = step-offset;
- }
-
- if(!vert)
- {
- olx = l; /* forcing top... */
- orx = r;
- oly = ory = -32000;
- }
- else
- {
- oly = t; /* forcing left... */
- ory = b;
- olx = orx = 32000;
- }
-
- for(i=0;i<nstep;i++)
- {
- int nlx, nrx, nly, nry;
- /* compute new division */
- if(!vert)
- {
- nlx = l;
- nrx = r;
- nly = y_horizon(l, v, offset);
- nry = y_horizon(r, v, offset);
- }
- else
- {
- nly = t;
- nry = b;
- nlx = x_horizon(t, v, offset);
- nrx = x_horizon(b, v, offset);
- }
-
- vx[0] = orx; // clip and render 4-vertex poly (most common)
- vy[0] = ory;
- vx[1] = olx;
- vy[1] = oly;
- vx[2] = nlx;
- vy[2] = nly;
- vx[3] = nrx;
- vy[3] = nry;
- render_ext_poly(4, vx, vy, *colorlist);
- colorlist += cd;
- olx = nlx;
- oly = nly;
- orx = nrx;
- ory = nry;
- offset += step;
- }
-
-
- vx[0] = orx; /* finish off last slice */
- vy[0] = ory;
- vx[1] = olx;
- vy[1] = oly;
- if(!vert)
- {
- i = 32000; /* force bottom */
- vx[2] = l;
- vy[2] = i;
- vx[3] = r;
- vy[3] = i;
- }
- else
- {
- i = -32000; /* force right */
- vx[2] = i;
- vy[2] = t;
- vx[3] = i;
- vy[3] = b;
- }
- render_ext_poly(4, vx, vy, *colorlist);
-
- }
-
-
- /*********** SKY/GROUNDCOLOR INTERFACE *********/
-
- static int h2colors[2] = { 0xAe, 0x8D }; // 2-color horizon default
-
- static int horizon_ncolors = 2; // cached clear arguments
- static int *horizon_colors = h2colors;
- static int horizon_stepsize = 48;
-
-
- void set_skycolor(int color)
- {
- h2colors[0] = color;
- horizon_colors = h2colors;
- horizon_ncolors = 2;
- if(h2colors[0]==h2colors[1]) horizon_ncolors = 1;
- }
-
- void set_groundcolor(int color)
- {
- h2colors[1] = color;
- horizon_colors = h2colors;
- horizon_ncolors = 2;
- if(h2colors[0]==h2colors[1]) horizon_ncolors = 1;
- }
-
-
- /*********** EXTERNAL HORIZON TYPE SETUP *********/
-
- // args: ncolor = 0 for no clear, others 0
- // ncolor = 1 for solid clear to skycolor, or skycolor=groundcolor
- // ncolor = 2 for normal horizon, or skycolor<>groundcolor
- // ncolor > 2 for banded horizon with array of colors from palette
- // leave bandsize 0 (unchanged), or use 128 for best size
-
- void set_horizon(int ncolors, int colors[16], int bandsize)
- {
- horizon_ncolors = ncolors;
- if(ncolors==0) return; // horizon off: ignore rest
-
- if(ncolors<3 && colors==NULL) horizon_colors = h2colors;
- if(colors!=NULL) horizon_colors = colors;
- if(bandsize) horizon_stepsize = bandsize;
- }
-
-
-
- /************* DRAW HORIZON/CLEAR WINDOW ************/
-
- void horizon(VIEW *v, int page) // clear window or draw horizon
- {
- set_drawpage(page);
- setup_hdwe(0);
-
- switch(horizon_ncolors)
- {
- case 0: // no clear: whole page done before?
- break;
-
- case 1: // solid clear window
- clr_block(v->left, v->top, v->right, v->bottom-1, page, horizon_colors[0]);
- break;
-
- case 2:
- band_horizon(v, page, 0, 1, horizon_colors);
- break;
-
- default:
- band_horizon(v, page, horizon_stepsize, horizon_ncolors-1, horizon_colors);
- break;
- }
- reset_hdwe();
- return;
- }
-
- // some test values
-
- //unsigned hcolors[20] = { 0xaf, 0xae, 0xad, 0xac, 0x79, 0x7a, 0x7b, 0x7c };
- //
- //test_h()
- //{
- // set_horizon(8, hcolors, 48);
- //}
-